/******************** (C) COPYRIGHT 2018 merafour ********************
* Author             : 冷月追风@merafour.blog.163.com
* Version            : V1.0.0
* Date               : 8/1/2019
* Description        : 设备同步与基本通讯指令.
********************************************************************************
* merafour.blog.163.com
* merafour@163.com
* github.com/Merafour
*******************************************************************************/
#ifndef QISERIALSYNC_H
#define QISERIALSYNC_H

#include "qiserialport.h"

class QiSerialSync : public QiSerialPort
{
    Q_OBJECT
public:
    explicit QiSerialSync(QObject *parent = nullptr);
    enum Code
    {
        // response codes
        NOP = 0x00,
        OK = 0x10,
        FAILED = 0x11,
        INSYNC = 0x12,
        INVALID = 0x13,//	# rev3+

        // protocol commands
        EOC = 0x50,
        GET_SYNC = 0x21,
        GET_DEVICE = 0x22,	// returns DEVICE_ID and FREQ bytes
        CHIP_ERASE = 0x23,
        CHIP_VERIFY = 0x24,//# rev2 only
        PROG_MULTI = 0x27,
        READ_MULTI = 0x28,//# rev2 only
        GET_CRC = 0x29,//	# rev3+
        GET_OTP = 0x2a, // read a byte from OTP at the given address
        GET_SN = 0x2b,    // read a word from UDID area ( Serial)  at the given address
        GET_CHIP = 0x2c, // read chip version (MCU IDCODE)
        PROTO_SET_DELAY	= 0x2d, // set minimum boot delay
        REBOOT = 0x30,
        STANDBY = 0x32,
        GET_ID = 0x33,
        ENCRYPT = 0x34,
        B2_SYNC = 0x35,
        GET_ID_TEA = 0x36,
        ENCRYPT_TEA = 0x37,
        GET_KEY = 0x38, // 交换私钥
        GET_ID_TEAD = 0x39, // 动态密钥
    };
    enum Info {
        BL_REV = 1,//	# bootloader protocol revision
        BOARD_ID = 2,//	# board type
        BOARD_REV = 3,//	# board revision
        FLASH_SIZE = 4,//	# max firmware size in bytes
        VEC_AREA = 5
    };
    enum SingalCode
    {
        // response codes
        DOWN  = 0x0180,
        CRC   = 0x0181,
        SCAN  = 0x0182,
        TIME  = 0x0183,
        ERR   = 0x0184,
        PULL  = 0x0185,
        MSG   = 0x0186,
        REPO  = 0x0187,  // Reported
    };
    int __scan(void);
    virtual void __send(const uint8_t buf[], const uint32_t len);
    int __sync(void);
    //void msg_to_ipmc(const uint8_t slave_addr, const uint8_t _msg, const uint8_t _eoc, const uint8_t buf[], const uint8_t lenght);
    //void msg_form_ipmc(const uint8_t slave_addr, const uint8_t _msg, const uint8_t _eoc, const uint8_t buf[], const uint8_t lenght);
    int __getSync(void);
    virtual int __recv(uint8_t buf[], const int count = 2)
    {
        return read(buf, count);
    }
    virtual uint8_t __recv(void)
    {
        return read();
    }
    int __recv_int(void);
    int __getInfo(Info param);
    void __reboot(void)
    {
        uint8_t buf[2];
        buf[0] = Code::REBOOT;
        buf[1] = Code::EOC;
        __send(buf, 2);
        flush();
        //QThread::msleep(10);
        watting_data(300); // 300ms
        __getSync();
    }
    int identify(void);

    int board_type;
    int board_rev;
    int fw_maxsize;
    int bl_rev;
signals:
    void sig_progress_update(const QString &titel, int value);

public slots:

protected:
    //int __program_sync;
};

#endif // MSERIALSYNC_H
